package com.gowants.pems.util;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.Instant;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
/**
 * 时间工具类
 * @author GJR
 *
 */
public class DateUtil
{
    private final static SimpleDateFormat sdfYear = new SimpleDateFormat("yyyy");
    private final static SimpleDateFormat sdfMonthDay = new SimpleDateFormat("MM-dd");
    private final static SimpleDateFormat sdfDay = new SimpleDateFormat("yyyy-MM-dd");
    private final static SimpleDateFormat sdfDays = new SimpleDateFormat("yyyyMMdd");
    private final static SimpleDateFormat sdfTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    private final static SimpleDateFormat sdfTimes = new SimpleDateFormat("yyyyMMddHHmmss");

    /**
     * 
     * <获取YYYY格式>
     * @return
     * @remake create by GJR 2019年4月26日 下午1:54:55
     */
    public static String getSdfTimes()
    {
        return sdfTimes.format(new Date());
    }

    /**
     * 
     * <获取YYYY格式>
     * @return
     * @remake create by GJR 2019年4月26日 下午1:55:04
     */
    public static String getYear()
    {
        return sdfYear.format(new Date());
    }

    /**
     * 
     * <获取YYYY-MM-DD格式>
     * @return
     * @remake create by GJR 2019年4月26日 下午1:55:13
     */
    public static String getDay()
    {
        return sdfDay.format(new Date());
    }

    /**
     * 
     * <获取YYYYMMDD格式>
     * @return
     * @remake create by GJR 2019年4月26日 下午1:55:20
     */
    public static String getDays()
    {
        return sdfDays.format(new Date());
    }
    //获取前一天 <获取YYYYMMDD格式>
    public static String getTopDays(int i)
    {
    	Date date = new Date();//获取当前时间  
    	Calendar calendar = Calendar.getInstance();  
    	calendar.setTime(date); 
    	calendar.add(Calendar.DATE, i);
        return sdfDays.format(calendar.getTime());
    }
    /**
     * 
     * <获取YYYY-MM-DD HH:mm:ss格式>
     * @return
     * @remake create by GJR 2019年4月26日 下午1:55:27
     */
    public static String getTime()
    {
        return sdfTime.format(new Date());
    }
    
    /**
     * 
     * <获取当前时间>
     * @return
     * @remake create by GJR 2019年5月7日 上午9:06:47
     */
    public static Date getDate() 
    {
        return new Date();
    }
    
    /**
     * 
     * <日期比较，如果s>=e 返回true 否则返回false>
     * @param s
     * @param e
     * @return
     * @remake create by GJR 2019年4月26日 下午1:55:34
     */
    public static boolean compareDate(String s, String e)
    {
        if (fomatDate(s) == null || fomatDate(e) == null)
        {
            return false;
        }
        return fomatDate(s).getTime() >= fomatDate(e).getTime();
    }

    /**
     * 
     * <格式化日期>
     * @param date
     * @return
     * @remake create by GJR 2019年4月26日 下午1:55:41
     */
    public static Date fomatDate(String date)
    {
        DateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
        try
        {
            return fmt.parse(date);
        } 
        catch (ParseException e)
        {
            e.printStackTrace();
            return null;
        }
    }
    
    /**
     * <格式化日期>
     * @param date
     * @return
     * @remake create by TPH 2019年9月10日 下午3:31:31
     */
    public static Date dateFormat(String date)
    {
        DateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try
        {
            return fmt.parse(date);
        } 
        catch (ParseException e)
        {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * <格式化日期>
     *
     * @param
     * @return
     * @remake create by GJR 2019/6/18 17:04
     */
    public static Date formatDate(String date)
    {
        try
        {
            return sdfTimes.parse(date);
        }
        catch (ParseException e)
        {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 
     * <格式化日期>
     * @param date
     * @return
     * @remake create by GJR 2019年5月22日 上午8:56:15
     */
    public static String fomatDate(Date date)
    {
        return sdfTime.format(date);
    }
    
    /**
     * <格式化日期>
     *
     * @param
     * @return
     * @remake create by GJR 2019/6/18 17:04
     */
    public static Date formatDate1(String date) 
    {
        try
        {
            return sdfTime.parse(date);
        }
        catch (ParseException e)
        {
            e.printStackTrace();
            return null;
        }
    }
    
    /**
     * 
     * <校验日期是否合法>
     * @param s
     * @return
     * @remake create by GJR 2019年4月26日 下午1:55:48
     */
    public static boolean isValidDate(String s)
    {
        DateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
        try
        {
            fmt.parse(s);
            return true;
        } 
        catch (Exception e)
        {
            // 如果throw java.text.ParseException或者NullPointerException，就说明格式不对
            return false;
        }
    }

    /**
     * 
     * <计算从开始时间至结束时间是多少年>
     * @param startTime
     * @param endTime
     * @return
     * @remake create by GJR 2019年4月26日 下午1:55:56
     */
    public static int getDiffYear(String startTime, String endTime)
    {
        DateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
        try
        {
            // long aa=0;
            int years = (int) (((fmt.parse(endTime).getTime() - fmt.parse(startTime).getTime()) / (1000 * 60 * 60 * 24)) / 365);
            return years;
        } 
        catch (Exception e)
        {
            // 如果throw java.text.ParseException或者NullPointerException，就说明格式不对
            return 0;
        }
    }

    /**
     * 
     * <时间相减得到天数>
     * @param beginDateStr
     * @param endDateStr
     * @return
     * @remake create by GJR 2019年4月26日 下午1:56:08
     */
    public static long getDaySub(String beginDateStr, String endDateStr)
    {
        long day = 0;
        java.text.SimpleDateFormat format = new java.text.SimpleDateFormat("yyyy-MM-dd");
        java.util.Date beginDate = null;
        java.util.Date endDate = null;

        try
        {
            beginDate = format.parse(beginDateStr);
            endDate = format.parse(endDateStr);
        } 
        catch (ParseException e)
        {
            e.printStackTrace();
        }
        day = (endDate.getTime() - beginDate.getTime()) / (24 * 60 * 60 * 1000);

        return day;
    }

    /**
     * 
     * <得到n天之后的日期>
     * @param days
     * @return
     * @remake create by GJR 2019年4月26日 下午1:56:16
     */
    public static String getAfterDayDate(String days)
    {
        int daysInt = Integer.parseInt(days);

        Calendar canlendar = Calendar.getInstance(); // java.util包
        canlendar.add(Calendar.DATE, daysInt); // 日期减 如果不够减会将月变动
        Date date = canlendar.getTime();

        SimpleDateFormat sdfd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateStr = sdfd.format(date);

        return dateStr;
    }

    /**
     * 
     * <得到n天之后是周几>
     * @param days
     * @return
     * @remake create by GJR 2019年4月26日 下午1:56:22
     */
    public static String getAfterDayWeek(String days)
    {
        int daysInt = Integer.parseInt(days);
        Calendar canlendar = Calendar.getInstance(); // java.util包
        canlendar.add(Calendar.DATE, daysInt); // 日期减 如果不够减会将月变动
        Date date = canlendar.getTime();
        SimpleDateFormat sdf = new SimpleDateFormat("E");
        String dateStr = sdf.format(date);
        return dateStr;
    }

    /**
     * 
     * <Date转Timestamp>
     * @param date
     * @return
     * @remake create by GJR 2019年4月26日 下午1:56:28
     */
    public static Timestamp dateToTimeStamp(Date date)
    {
        Timestamp timeStamp = new Timestamp(date.getTime());

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String timeStr = sdf.format(timeStamp);

        try
        {
            timeStamp = Timestamp.valueOf(timeStr);
        } 
        catch (Exception e)
        {
            e.printStackTrace();
        }

        return timeStamp;
    }
    
    /**
     * 
     * <返回N月之后的日期>
     * @param date
     * @param month
     * @return
     * @remake create by GJR 2019年4月26日 下午1:56:37
     */
    public static Date setMonth(Date date, int month) 
    {
        // 设置给定时间
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        // 偏移月份
        c.add(Calendar.MONTH, +month);
        return c.getTime();
    }

    /**
     *
     * <返回N天之后的日期>
     * @param date
     * @param day
     * @return
     * @remake create by GJR 2019年4月26日 下午1:56:37
     */
    public static Date setDay(Date date, int day)
    {
        // 设置给定时间
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        // 偏移月份
        c.add(Calendar.DATE, +day);
        return c.getTime();
    }

    /**
     * <获取N小时之后>
     *
     * @param
     * @return
     * @remake create by GJR 2019/5/29 9:24
     */
    public static Date getHoursAfter(Date date, int hours)
    {
        // 设置给定时间
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        // 偏移小时
        c.add(Calendar.HOUR, +hours);
        return c.getTime();
    }

    /**
     * <获取N小时之前>
     *
     * @param
     * @return
     * @remake create by GJR 2019/5/29 9:25
     */
    public static Date getHoursBefore(Date date, int hours)
    {
        // 设置给定时间
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        // 偏移小时
        c.add(Calendar.HOUR, -hours);
        return c.getTime();
    }

    /**
     * 
     * <获取当前的零点>
     * @return
     * @remake create by GJR 2019年5月22日 上午8:50:09
     */
    public static Date getTodayZero() 
    {
        return getTodayZero(new Date());
    }
    
    public static Date getTodayEnd() 
    {
	    long current=System.currentTimeMillis();    //当前时间毫秒数
	    long zeroT=current/(1000*3600*24)*(1000*3600*24)- TimeZone.getDefault().getRawOffset();  //今天零点零分零秒的毫秒数
	    String zero = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(zeroT);
	    long endT=zeroT+24*60*60*1000-1;  //今天23点59分59秒的毫秒数
	    String end = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(endT);
	    
	    return DateUtil.dateFormat(end);
    }
    /**
     * 
     * <获取指定时间的当天零点>
     * @param date 指定的时间
     * @return
     * @remake create by GJR 2019年5月22日 上午8:49:43
     */
    public static Date getTodayZero(Date date) 
    {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }
    
    /**
     * 
     * <获取指定时间的当天零点>
     * @param date 指定的时间字符串
     * @return
     * @remake create by GJR 2019年5月22日 上午8:49:43
     */
    public static Date getTodayZero(String date) 
    {
        return getTodayZero(fomatDate(date));
    }

    /**
     * 获取本周周一0点
     * @return
     */
    public static Date getWeekFirt()
    {
        return getWeekFirt(new Date());
    }

    /**
     * 获取指定日期所在周的周一0点
     * @return
     */
    public static Date getWeekFirt(Date date)
    {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.setFirstDayOfWeek(Calendar.MONDAY);// 设置一个星期的第一天，按中国的习惯一个星期的第一天是星期一
        int dayWeek = calendar.get(Calendar.DAY_OF_WEEK);// 获得当前日期是一个星期的第几天
        if(dayWeek==1){
            dayWeek = 8;
        }
        System.out.println("要计算日期为:" + sdfDay.format(calendar.getTime())); // 输出要计算日期

        calendar.add(Calendar.DATE, calendar.getFirstDayOfWeek() - dayWeek);// 根据日历的规则，给当前日期减去星期几与一个星期第一天的差值
        return getTodayZero(calendar.getTime());
    }

    /**
     * 获取指定日期所在周的周一0点
     * @param date
     * @return
     */
    public static Date getWeekFirt(String date)
    {
        return getWeekFirt(fomatDate(date));
    }

    /**
     * 获取周天最后一秒
     * @return
     */
    public static Date getSunDay()
    {
        return getSunDay(new Date());
    }

    /**
     * 获取周天最后一秒
     * @return
     */
    public static Date getSunDay(Date date)
    {
        Date monday = getWeekFirt(date);
        Date sunday = setDay(monday, 7);
        return getMaxTime(sunday);
    }

    /**
     * 获取周天最后一秒
     * @return
     */
    public static Date getSunDay(String date)
    {
        return getSunDay(fomatDate(date));
    }

    /**
     * 某天最大时间
     * @param date
     * @return
     */
    public static Date getMaxTime(Date date)
    {
        LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(date.getTime()), ZoneId.systemDefault());;
        LocalDateTime endOfDay = localDateTime.with(LocalTime.MAX);
        return Date.from(endOfDay.atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * 获取日期所在月的第一天0点
     * @param date
     * @return
     */
    public static Date getMonthFirstDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMinimum(Calendar.DAY_OF_MONTH));

        return getTodayZero(calendar.getTime());
    }

    /**
     * 获取某月最后一秒
     * @return
     */
    public static Date getMonthLastDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        return getMaxTime(calendar.getTime());
    }

    /**
     * 某时间所在季度开始
     *
     * @return
     */
    public static Date getCurrentQuarterStartTime(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int currentMonth = calendar.get(Calendar.MONTH) + 1;
        Date now = null;
        try {
            if (currentMonth >= 1 && currentMonth <= 3)
                calendar.set(Calendar.MONTH, 0);
            else if (currentMonth >= 4 && currentMonth <= 6)
                calendar.set(Calendar.MONTH, 3);
            else if (currentMonth >= 7 && currentMonth <= 9)
                calendar.set(Calendar.MONTH, 4);
            else if (currentMonth >= 10 && currentMonth <= 12)
                calendar.set(Calendar.MONTH, 9);
            calendar.set(Calendar.DATE, 1);
            now = getTodayZero(calendar.getTime());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return now;
    }

    /**
     *
     * 时间格式化成 月-日 如 05-01
     * @param date
     * @return
     */
    public static String fomatDateToMonthDay(Date date)
    {
        return sdfMonthDay.format(date);
    }

    /**
     * 某时间所在季度结束
     *
     * @return
     */
    public static Date getCurrentQuarterEndTime(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int currentMonth = calendar.get(Calendar.MONTH) + 1;
        Date now = null;
        try {
            if (currentMonth >= 1 && currentMonth <= 3) {
                calendar.set(Calendar.MONTH, 2);
                calendar.set(Calendar.DATE, 31);
            } else if (currentMonth >= 4 && currentMonth <= 6) {
                calendar.set(Calendar.MONTH, 5);
                calendar.set(Calendar.DATE, 30);
            } else if (currentMonth >= 7 && currentMonth <= 9) {
                calendar.set(Calendar.MONTH, 8);
                calendar.set(Calendar.DATE, 30);
            } else if (currentMonth >= 10 && currentMonth <= 12) {
                calendar.set(Calendar.MONTH, 11);
                calendar.set(Calendar.DATE, 31);
            }
            now = getMaxTime(calendar.getTime());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return now;
    }

    /**
     * 某时间所在年开始
     * @return
     */
    public static Date getCurrentYearStartTime(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        Date now = null;
        try {
            calendar.set(Calendar.MONTH, 0);
            calendar.set(Calendar.DATE, 1);
            now = getTodayZero(calendar.getTime());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return now;
    }

    /**
     * 当前年的结束时间，即2012-12-31 23:59:59
     *
     * @return
     */
    public static Date getCurrentYearEndTime(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        Date now = null;
        try {
            calendar.set(Calendar.MONTH, 11);
            calendar.set(Calendar.DATE, 31);
            now = getMaxTime(calendar.getTime());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return now;
    }

    /**
     * 取得当月天数
     * */
    public static int getCurrentMonthLastDay(Date date)
    {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DATE, 1);//把日期设置为当月第一天
        calendar.roll(Calendar.DATE, -1);//日期回滚一天，也就是最后一天
        return calendar.get(Calendar.DATE);
    }

    /**
     * 获取时间月份
     * @param date
     * @return
     */
    public static int getMonth(String date)
    {
        return getMonth(fomatDate(date));
    }

    /**
     * 获取时间月份
     * @param date
     * @return
     */
    public static int getMonth(Date date)
    {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.MONDAY) + 1;
    }
    /**
     * 月份设置
     * @param date
     * @param month
     * @return
     */
    public static Date setAnyMonth(String date, int month)
    {
        return setAnyMonth(fomatDate(date), month);
    }

    /**
     * 月份设置
     * @param date
     * @param month
     * @return
     */
    public static Date setAnyMonth(Date date, int month)
    {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.MONTH, month - 1);
        return calendar.getTime();
    }

    /**
     * 获取月份所在季度第一个月
     * @param date
     * @return yyyy-mm-dd  年-月-日
     */
    public static String getFirstMonthInQuarter(Date date)
    {
        int month = getMonth(date);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);

        switch((month - 1) / 3)
        {
            // 第一季度
            case 0 :
                calendar.set(Calendar.MONTH, 0);
                break;
            // 第二季度
            case 1 :
                calendar.set(Calendar.MONTH, 3);
                break;
            // 第三季度
            case 2 :
                calendar.set(Calendar.MONTH, 8);
                break;
            // 第四季度
            case 3 :
                calendar.set(Calendar.MONTH, 11);
                break;
        }
        calendar.set(Calendar.DATE, 1);
        return sdfDay.format(calendar.getTime());
    }

    /**
     * TODO 准备删除方法，禁止调用
     * <获取指定计量单位类型的未来时间>
     * @param currDate 当前时间
     * @param type 计量单位类型  day week month quarter year
     * @return 未来时间
     * @remake create by GJR 2019年5月22日 下午1:48:27
     */
    public static Date getFutureDate(Date currDate, String type) 
    {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(currDate);
        
        switch(type) 
        {
            // 加一个小时
            case "hours" :
                calendar.add(Calendar.HOUR, 1);
                break;
            // 加一天
            case "day" : 
                calendar.add(Calendar.DATE, 1);
                break;
            // 加一周
            case "week" : 
                calendar.add(Calendar.DATE, 7);
                break;
            // 加一个月
            case "month" : 
                calendar.add(Calendar.MONTH, 1);
                break;
            // 加三个月(一个季度)
            case "quarter" : 
                calendar.add(Calendar.MONTH, 3);
                break;
            // 加一年
            case "year" : 
                calendar.add(Calendar.YEAR, 1);
                break;
        }
        
        return calendar.getTime();
    }
    
    
    /**
     * utc转北京时间
     * @param date  格式为 ddmmyy hhmmss.sss  例如:231120 142259.011
     * @return
     */
    public static String getBeijingTime(String date)
    {
    	String formatPattern = "yyyy-MM-dd HH:mm:ss";
       
        String[] date1=date.split(" ");
        String date2=date1[0];
        String date3=date1[1];
        String yy=date2.substring(4,6);
        String MM=date2.substring(2,4);
        String dd=date2.substring(0,2);
        
        String[] date4=date3.split("\\.");
        String date5=date4[0];
        String date6=date4[1];
        
        String hh=date5.substring(0,2);
        String mm=date5.substring(2,4);
        String ss=date5.substring(4,6);
        
        String sss=date6;
        
        String utc = "20"+yy+"-"+MM+"-"+dd+"T"+hh+":"+mm+":"+ss+"."+sss+"Z";//2019-07-10T16:00:00.000Z
        ZonedDateTime zdt  = ZonedDateTime.parse(utc);
        LocalDateTime localDateTime = zdt.toLocalDateTime();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(formatPattern);
        String gst = formatter.format(localDateTime.plusHours(8));
        return gst;
    }
    public static void main(String[] args)
    {
//        Date endDate = getFutureDate(new Date(), "year");
//        System.out.println(fomatDate(endDate));
//        System.out.println(fomatDate(getWeekFirt()));
//        System.out.println(fomatDate(getMonthFirstDay(new Date())));
//        System.out.println(fomatDate(getMonthLastDay(new Date())));
//        System.out.println(fomatDate(getCurrentQuarterStartTime(new Date())));
//        System.out.println(fomatDate(getCurrentQuarterEndTime(new Date())));
//        System.out.println(fomatDate(getCurrentYearStartTime(new Date())));
//        System.out.println(fomatDate(getCurrentYearEndTime(new Date())));
//        System.out.println(getCurrentMonthLastDay(new Date()));
//        System.out.println(fomatDateToMonthDay(new Date()));
//        System.out.println(getMonth(new Date()));
//        System.out.println(fomatDate(setAnyMonth(new Date(), 3)));
//        System.out.println(getFirstMonthInQuarter(new Date()));
//        System.out.println(fomatDate(getHoursAfter(new Date(), 2)));
//        System.out.println(fomatDate(getHoursBefore(new Date(), 2)));
//        System.out.println(formatDate("2019/06/18 23:23:59"));
    	
    	System.out.println(getBeijingTime("231120 142259.011"));
    	
    }
}
